import axios, { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios'
import { ElMessage } from 'element-plus'
import { getMessageInfo } from './status'

interface IBaseResp<T = any> {
	code: number | string
	message: string
	data: T
	status?: number | string
}

const service: AxiosInstance = axios.create({
	baseURL:
		import.meta.env.VITE_APP_USE_MOCK === 'true'
			? import.meta.env.VITE_APP_MOCK_BASE_URL
			: import.meta.env.VITE_APP_API_BASE_URL,
	timeout: 5000
})

// 请求拦截
service.interceptors.request.use(
	(config: InternalAxiosRequestConfig) => {
		return config
	},
	(error: AxiosError) => {
		return Promise.reject(error)
	}
)

service.interceptors.response.use(
	(response: AxiosResponse) => {
		if (response.status === 200) {
			return response
		}
		ElMessage({
			message: getMessageInfo(response.status),
			type: 'error'
		})
		return response
	},
	(error) => {
		const { response } = error
		console.log(response)
		if (response) {
			ElMessage({
				message: getMessageInfo(response.status),
				type: 'error'
			})
			return Promise.reject(response.data)
		}
		ElMessage({
			message: '网络开小差了',
			type: 'error'
		})
	}
)

const requestInstance = <T = any>(config: AxiosRequestConfig): Promise<T> => {
	const conf = config
	return new Promise((resolve, reject) => {
		service.request<any, AxiosResponse<IBaseResp>>(conf).then((res: AxiosResponse<IBaseResp>) => {
			const data = res.data
			// 如果data.code为错误代码返回message信息
			if (data.code != 0) {
				ElMessage({
					message: data.message,
					type: 'error'
				})
				reject(data.message)
			} else {
				ElMessage({
					message: data.message,
					type: 'success'
				})
				// 此处返回data信息 也就是 api 中配置好的 Response类型
				resolve(data.data as T)
			}
		})
	})
}

// 在最后使用封装过的axios导出不同的请求方式
export function get<T = any, U = any>(url: string, params: U, config?: AxiosRequestConfig): Promise<T> {
	return requestInstance({ ...config, url, method: 'GET', params })
}

export function post<T = any, U = any>(url: string, data: U, config?: AxiosRequestConfig): Promise<T> {
	return requestInstance({ ...config, url, method: 'POST', data: data })
}
